/*
 *Copyright (c) [2019-2020]  C2comm, Inc.  All rights reserved.
 *
 *This program is free software; you can redistribute it and/or
 *modify it under the terms of the GNU General Public License
 *as published by the Free Software Foundation; either version 2
 *of the License, or (at your option) any later version.
 *
 *This program is distributed in the hope that it will be useful,
 *but WITHOUT ANY WARRANTY; without even the implied warranty of
 *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *GNU General Public License for more details.
 *
 *You should have received a copy of the GNU General Public License
 *along with this program; If not, see <https://www.gnu.org/licenses/>
 */

/*
 *Vendor: C2comm
 *Version: 1.0
 *Filename: SMStable.v
 *Target Device: Altera
 *Author : sunxiaotian@c2comm.cn
*/

module SMStable(
 input wire         SYS2CORE_clk,
 input wire         SYS2CORE_rst_n,
 input wire [19:0]  GA2STA_local_clk,
 input wire         GA2STA_guard_pcf_valid,
 input wire [1:0]   GA2STA_guard_pcf,
 output reg         STA2GA_guard_pcf_ready,
 input wire [7:0]   GA2STA_guard_stable_cycle_ctr,
 input wire [88:0]  GA2STA_guard_conf,
 input wire [3:0]   GA2STA_guard_clique_in,
 output reg         STA2CS_cmd_valid,
 output reg [7:0]   STA2CS_cmd_next_top_state,
 output wire [9:0]  STA2CS_cmd_bottom_state,
 input wire [7:0]   current_top_state,
 output reg         STA2CS_cmd_next_top_state_valid
);



reg [9:0] SMStable_state;

parameter  INIT_S=10'b00_0000_0001,
           MATCH_S=10'b00_0000_0010,
           COMPLETE_S=10'b00_0000_0100,
           C0_S=10'b00_0000_1000,
           C1_S=10'b00_0001_0000,
           C2_S=10'b00_0010_0000,
		   C3_S=10'b00_0100_0000,
		   C4_S=10'b00_1000_0000,
		   C5_S=10'b01_0000_0000,
		   C6_S=10'b10_0000_0000;
           
assign  STA2CS_cmd_bottom_state=SMStable_state; 
        
always@(posedge SYS2CORE_clk or negedge  SYS2CORE_rst_n )begin
    if(~SYS2CORE_rst_n)begin
        STA2CS_cmd_valid<=1'b0;
        STA2CS_cmd_next_top_state<=8'd0;
        STA2CS_cmd_next_top_state_valid<=1'b0;
        STA2GA_guard_pcf_ready<=1'b1;
        SMStable_state<=INIT_S;
    end 
    else begin
        case(SMStable_state)
            INIT_S:begin
                STA2CS_cmd_valid<=1'b0;
                STA2CS_cmd_next_top_state_valid<=1'b0;
                STA2CS_cmd_next_top_state<=8'd0;
                STA2GA_guard_pcf_ready<=1'b1;  
                if(current_top_state==8'b1000_0000)begin
                    SMStable_state<=MATCH_S;
                end 
                else begin
                    SMStable_state<=INIT_S;
                end
                
            end
            MATCH_S:begin
                if(GA2STA_guard_pcf_valid==1'b1&&GA2STA_guard_pcf[1:0]==2'b01&&GA2STA_guard_conf[88]==1'b1)begin  //CA
                    STA2GA_guard_pcf_ready<=1'b0;  
                    SMStable_state<=C6_S;
                end 
                else if(GA2STA_local_clk==GA2STA_guard_conf[39:20]&&GA2STA_guard_clique_in[2]==1'b1) begin
                    STA2GA_guard_pcf_ready<=1'b0;  
                    SMStable_state<=C0_S;
                end 
                else if(GA2STA_local_clk==GA2STA_guard_conf[79:60]&&GA2STA_guard_clique_in[3]==1'b1) begin
                    STA2GA_guard_pcf_ready<=1'b0;  
                    SMStable_state<=C1_S;
                end 
				else if(GA2STA_local_clk==GA2STA_guard_conf[59:40]&&GA2STA_guard_clique_in[0]==1'b1&&
						GA2STA_guard_stable_cycle_ctr[7:0]<GA2STA_guard_conf[87:80]) begin
                    STA2GA_guard_pcf_ready<=1'b0;  
                    SMStable_state<=C2_S;
                end 
				else if(GA2STA_local_clk==GA2STA_guard_conf[59:40]&&GA2STA_guard_clique_in[0]==1'b1&&
						GA2STA_guard_stable_cycle_ctr[7:0]>=GA2STA_guard_conf[87:80]) begin
                    STA2GA_guard_pcf_ready<=1'b0;  
                    SMStable_state<=C3_S;
                end 
				else if(GA2STA_local_clk==GA2STA_guard_conf[59:40]&&GA2STA_guard_clique_in[1]==1'b1) begin
                    STA2GA_guard_pcf_ready<=1'b0;  
                    SMStable_state<=C4_S;
				end
				else if((GA2STA_local_clk+1'b1)==GA2STA_guard_conf[19:0]) begin
                    STA2GA_guard_pcf_ready<=1'b0;  
                    SMStable_state<=C5_S;
				end
                else begin
                    STA2GA_guard_pcf_ready<=1'b1; 
                    SMStable_state<=MATCH_S;
                end     
            end 
            C0_S:begin
                STA2CS_cmd_next_top_state_valid<=1'b1;
                STA2CS_cmd_next_top_state[7:0]<=8'b0000_0001; //SM_INTEGRATE
                STA2GA_guard_pcf_ready<=1'b0;
                SMStable_state<=COMPLETE_S;
            end 
            C1_S:begin
                STA2CS_cmd_next_top_state_valid<=1'b1;
                STA2CS_cmd_next_top_state[7:0]<=8'b1000_0000; //SM_STABLE
                STA2GA_guard_pcf_ready<=1'b0;
                SMStable_state<=COMPLETE_S;
            end
            C2_S:begin
                STA2CS_cmd_next_top_state_valid<=1'b1;
                STA2CS_cmd_next_top_state[7:0]<=8'b1000_0000; //SM_STABLE
                STA2GA_guard_pcf_ready<=1'b0;
                SMStable_state<=COMPLETE_S;
            end
            C3_S:begin
                STA2CS_cmd_next_top_state_valid<=1'b1;
                STA2CS_cmd_next_top_state[7:0]<=8'b0000_0001; //SM_INTEGRATE
                STA2GA_guard_pcf_ready<=1'b0;
                SMStable_state<=COMPLETE_S;
            end
			C4_S:begin
                STA2CS_cmd_next_top_state_valid<=1'b1;
                STA2CS_cmd_next_top_state[7:0]<=8'b1000_0000; //SM_STABLE
                STA2GA_guard_pcf_ready<=1'b0;
                SMStable_state<=COMPLETE_S;
            end
			C5_S:begin
                STA2CS_cmd_next_top_state_valid<=1'b1;
                STA2CS_cmd_next_top_state[7:0]<=8'b1000_0000; //SM_STABLE
                STA2GA_guard_pcf_ready<=1'b0;
                SMStable_state<=COMPLETE_S;
            end
			C6_S:begin
                STA2CS_cmd_next_top_state_valid<=1'b1;
                STA2CS_cmd_next_top_state[7:0]<=8'b0001_0000; //SM_WAIT_4_CYCLE_START_CS
                STA2GA_guard_pcf_ready<=1'b0;
                SMStable_state<=COMPLETE_S;
            end
            COMPLETE_S:begin
                STA2CS_cmd_next_top_state_valid<=1'b0;
                SMStable_state<=INIT_S; 
            end 
        endcase
    end 

end 



endmodule